﻿using System;
using System.Xml;
using System.Collections.Generic;
using Mesuro.Common;
using System.IO;
using System.Text;
namespace Mesuro.DataManagement {

	public class Payload : DefaultMutableSeries, IXmlSerialisable {
		public const double DEFAULT_FILE_VERSION = 1.0;

		private class DatabaseChannel : DefaultMutableChannel {
			public double Mean { get; set; }
		}

		private readonly string source;
		private readonly double fileVersion;

		public bool IsLoaded { get; private set; }

		public Payload( XmlElement element ) {
			source = element.GetAttribute( "location" );
			double tFV = DEFAULT_FILE_VERSION;
			try {
				tFV = Double.Parse( element.GetAttribute( "version" ) );
			} catch (Exception) { }
			fileVersion = tFV;
			//I have chosen to ignore file type for now
			XmlNodeList colElems = element.GetElementsByTagName( "mesuro:column" );

			foreach (XmlElement colElem in colElems) {

				String name = MakeChannelName( colElem.GetAttribute( "name" ) );
				Limits lims = new Limits();
				double meanVal = double.NaN;

				foreach (XmlElement param in colElem.GetElementsByTagName( "mesuro:parameter" )) {
					string pName = param.GetAttribute( "name" );
					if (pName.Equals( "min" ))
						lims.Min = double.Parse( param.InnerText );
					else if (pName.Equals( "max" ))
						lims.Max = double.Parse( param.InnerText );
					else if (pName.Equals( "mean" ))
						meanVal = double.Parse( param.InnerText );
				}

				AddChannel( new DatabaseChannel() { Name = name, Limits = lims, Mean = meanVal } );

			}
		}

		private string MakeChannelName( string input ) {
			StringBuilder sb = new StringBuilder();
			IEnumerator<char> it = input.GetEnumerator();

			if (!it.MoveNext())
				throw new ArgumentException( "Empty string can't be made valid" );

			while (!(Char.IsLetter( it.Current ) || it.Current == '_'))
				it.MoveNext();

			do {
				if (Char.IsLetterOrDigit( it.Current ) || it.Current == '_')
					sb.Append( it.Current );
			} while (it.MoveNext());
			return sb.ToString();
		}

		public void ReadCSV( bool reload = false ) {
			if (IsLoaded) return;
			FileStream fs = File.OpenRead( source );
			StreamReader reader = new StreamReader( fs );
			string line;
			//Foreach line in file
			while ((line = reader.ReadLine()) != null) {
				//split on each comma
				String[] split = line.Split( ',' );

				Vector datum = new Vector( Channels.Count );
				double tmp;
				//foreach column
				for (int i = 0; i < Channels.Count; i++)
					//add that datapoint to memory
					datum[i] = Double.TryParse( split[i], out tmp ) ? tmp : double.NaN;

				AddDatum( datum );
			}
			IsLoaded = true;
		}

		public XmlElement XMLSerialise( XmlDocument doc ) {
			throw new NotImplementedException();
		}
	}
}